using NCrontab;

namespace MQTTDebugTool.Utils;

public abstract class TimerTask
{
    protected readonly Poller Poller;
    
    protected readonly TimerTaskEventArgs Args = new TimerTaskEventArgs();
    protected abstract void PollerExecute(TimerTaskEventArgs args);

    protected TimerTask(int millisecondsTimeout)
    {
        Poller = new Poller( () =>
        {
            PollerExecute(Args);
            Args.Update();
        }, millisecondsTimeout);
    }

    public virtual TimerTask Start()
    {
        Poller.Run();
        return this;
    }
    
    public virtual TimerTask Stop()
    {
        Poller.Kill();
        return this;
    }
    
}

public class ScheduledTask(string cron, Action<TimerTaskEventArgs> taskAction) : TimerTask(1000)
{
    private readonly CrontabSchedule _schedule = CrontabSchedule.Parse(cron, new CrontabSchedule.ParseOptions()
    {
        IncludingSeconds = cron.Split(' ').Length == 6
    });

    protected override void PollerExecute(TimerTaskEventArgs args)
    {
        DateTimeOffset nextExecuteTime = _schedule.GetNextOccurrence(DateTime.UtcNow);
        if (nextExecuteTime.ToUnixTimeSeconds() <= DateTimeOffset.UtcNow.AddSeconds(1).ToUnixTimeSeconds())
        {
            taskAction(Args);
        }
    }
    
}

public class DelayTask(int millisecondsTimeout, int count, Action<TimerTaskEventArgs> taskAction)
    : TimerTask(millisecondsTimeout)
{
    protected override void PollerExecute(TimerTaskEventArgs args)
    {
        if (args.ExecuteCount < count)
        {
            taskAction(Args);
        }
        else
        {
            Poller.Kill();
        }
    }
}

